#include <string.h>
#include <lua.h>
#include <lauxlib.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#include <pthread.h>
#include "quicklz.h"

#if QLZ_STREAMING_BUFFER > 0
    #error Define QLZ_STREAMING_BUFFER to 0 for this lib
#endif

static int lcompress(lua_State *L){
	qlz_state_compress *state=lua_touserdata(L,1);
	size_t size=0;
	const char * source=luaL_checklstring(L,2,&size);
	char compressed[size+400];
	memset(compressed,0,sizeof(compressed));
	int r = qlz_compress(source, compressed, size, state);
	lua_pushlstring(L,compressed,r);
	return 1;
}

static int ldecompress(lua_State *L){
	qlz_state_decompress *state=lua_touserdata(L,1);

	size_t size=0;
	const char * source=luaL_checklstring(L,2,&size);
	const size_t len=qlz_size_decompressed(source);
	char decompressed[len];
	int r = qlz_decompress(source, decompressed, state);
	lua_pushlstring(L,decompressed,r);
	return 1;
}

static int lnewcompress(lua_State *L){
	lua_newuserdata(L,sizeof(qlz_state_compress));
	if (luaL_newmetatable(L, "__compressmeta")) {
		luaL_Reg l[] = {
			{"compress",lcompress},
			{ NULL, NULL },
		};
		luaL_newlib(L, l);
		lua_setfield(L, -2, "__index");
	}
	lua_setmetatable(L, -2);
	return 1;	
}

static int lnewdecompress(lua_State *L){
	//qlz_state_decompress *state=lua_newuserdata(L,sizeof(qlz_state_decompress));
	lua_newuserdata(L,sizeof(qlz_state_decompress));
	if (luaL_newmetatable(L, "__decompressmeta")) {
		luaL_Reg l[] = {
			{"decompress",ldecompress},
			{ NULL, NULL },
		};
		luaL_newlib(L, l);
		lua_setfield(L, -2, "__index");
	}
	lua_setmetatable(L, -2);
	return 1;	
}

int luaopen_quicklz(lua_State *L) {
    luaL_Reg reg[] = {
		{"newcompress",lnewcompress},
		{"newdecompress",lnewdecompress},
		{NULL,NULL}
	};
	luaL_checkversion(L);
	luaL_newlib(L, reg);
	return 1;
}
